package com.gxar.quick.ar.server.db.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
import com.gxar.common.entity.PageResult;
import com.gxar.common.entity.Result;
import com.gxar.common.entity.login.UserProfile;
import com.gxar.common.exception.APIRuntimeException;
import com.gxar.common.utils.DateTimeUtils;
import com.gxar.common.utils.PageUtils;
import com.gxar.quick.ar.server.base.common.constant.UserConstant;
import com.gxar.quick.ar.server.base.common.enums.*;
import com.gxar.quick.ar.server.base.common.properties.UserProperties;
import com.gxar.quick.ar.server.base.common.utils.RandomNameUtil;
import com.gxar.quick.ar.server.base.model.ResultCodeEnum;
import com.gxar.quick.ar.server.base.model.combo.mapper.ComboMapStruct;
import com.gxar.quick.ar.server.base.model.combo.vo.ComboConfigInfoVO;
import com.gxar.quick.ar.server.base.model.combo.vo.response.ComboListResponse;
import com.gxar.quick.ar.server.base.model.exchange.dto.ExchangeItemSendUserStatisticsDTO;
import com.gxar.quick.ar.server.base.model.pay.info.WechatPrepayAttachInfo;
import com.gxar.quick.ar.server.base.model.user.dto.WorkStatisticsDTO;
import com.gxar.quick.ar.server.base.model.user.mapper.FeedbackMapStruct;
import com.gxar.quick.ar.server.base.model.user.mapper.UserMapStruct;
import com.gxar.quick.ar.server.base.model.user.mapper.UserMapStructImpl;
import com.gxar.quick.ar.server.base.model.user.vo.UserConfigVO;
import com.gxar.quick.ar.server.base.model.user.vo.request.ChangeConfigRequest;
import com.gxar.quick.ar.server.base.model.user.vo.request.FeedbackRequest;
import com.gxar.quick.ar.server.base.model.user.vo.response.*;
import com.gxar.quick.ar.server.base.model.works.dto.WorksContentDTO;
import com.gxar.quick.ar.server.base.reference.FileReference;
import com.gxar.quick.ar.server.base.reference.UaaReference;
import com.gxar.quick.ar.server.base.reference.UserReference;
import com.gxar.quick.ar.server.db.mapper.*;
import com.gxar.quick.ar.server.db.model.*;
import com.gxar.quick.ar.server.db.repository.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.common.utils.CollectionUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StopWatch;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author linsy
 * @version 1.0
 * @created 2023/11/6 17:58
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class UserService {
    // 配置
    private final UserProperties userProperties;
    // 数据层
    private final FeedbackRepository feedbackRepository;
    private final FeedbackMapper feedbackMapper;
    private final UserInfoMapper userInfoMapper;
    private final UserConfigMapper userConfigMapper;
    private final ComboRepository comboRepository;
    private final WorksMapper worksMapper;
    private final SlotMapper slotMapper;
    private final ComboMapper comboMapper;
    private final UserInfoRepository userInfoRepository;
    private final UserConfigRepository userConfigRepository;
    private final UserWorksMapper userWorksMapper;
    private final WorksDraftMapper worksDraftMapper;
    private final WorksPreviewMapper worksPreviewMapper;
    private final WorksTemplateRepository worksTemplateRepository;
    private final MaterialMapper materialMapper;
    private final ExchangeItemSendRecordMapper exchangeItemSendRecordMapper;
    // rpc调用
    private final FileReference fileReference;
    private final UaaReference uaaReference;

    private final UserReference userReference;

    public UserInfoResponse userInfo(UserProfile userProfile) {
        Long userId = userProfile.getId();
        UserInfoEntity userInfoEntity = userInfoMapper.findByUserId(userId);
        if (Objects.isNull(userInfoEntity)) {
            throw new APIRuntimeException(ResultCodeEnum.USER_NOT_EXIST);
        }
        UserConfigEntity userConfigEntity = userConfigMapper.findByUserIdAndItem(userId, ComboConfigItemEnum.IMPRESSIONS.getCode());
        if (Objects.isNull(userConfigEntity)) {
            throw new APIRuntimeException(ResultCodeEnum.USER_CONFIG_NOT_EXIST);
        }
        UserInfoResponse userInfoResponse = UserMapStruct.INSTANCE.entityToInfoResponse(userInfoEntity);
        userInfoResponse.setTotalImpressionsNumber(userConfigEntity.getAvailable());
        userInfoResponse.setName(StringUtils.isBlank(userProfile.getNickname()) ? userInfoEntity.getName() : userProfile.getNickname());
        userInfoResponse.setAvatar(StringUtils.isBlank(userProfile.getAvatar()) ? userProperties.getDefaultAvatar() : userProfile.getAvatar());
        Long comboId = userInfoEntity.getComboId();
        if (Objects.nonNull(comboId)) {
            Optional<ComboEntity> comboEntityOptional = comboRepository.findById(comboId);
            if (comboEntityOptional.isPresent()) {
                ComboEntity comboEntity = comboEntityOptional.get();
                userInfoResponse.setComboGrade(comboEntity.getGrade());
                ComboGradeEnum comboGradeEnum = ComboGradeEnum.getByCode(comboEntity.getGrade());
                if (Objects.nonNull(comboGradeEnum)) {
                    userInfoResponse.setComboGradeName(comboGradeEnum.getNickName());
                }
            }
        }
        WorkStatisticsDTO impressions = worksMapper.workImpressionsStatistics(userId);
        userInfoResponse.setUseImpressionsNumber(impressions != null ? impressions.getImpressions() : 0);
        return userInfoResponse;
    }

    /**
     * 校验用户权益
     *
     * @param userProfile 用户信息
     * @param items       查询的计费项
     * @return 剩余权益
     */
    public UserRightsResponse userRights(UserProfile userProfile, String items) {
        Map<Integer, ComboConfigItemEnum> itemMap = this.getQueryItem(items);
        if (StringUtils.isNotBlank(items) && itemMap.isEmpty()) {
            throw new APIRuntimeException(ResultCodeEnum.USER_RIGHT_PARAM_ITEM_ERROR);
        }
        return this.userRights(userProfile, itemMap);
    }

    /**
     * 查询用户权益
     *
     * @param userProfile 用户信息
     * @param itemMap     查询计费项
     * @return 响应
     */
    public UserRightsResponse userRights(UserProfile userProfile, Map<Integer, ComboConfigItemEnum> itemMap) {
        Long userId = userProfile.getId();
        List<UserConfigEntity> userConfigEntityList = userConfigMapper.findByUserId(userId);
        UserRightsResponse response = new UserRightsResponse();
        if (CollectionUtils.isEmpty(userConfigEntityList)) {
            return response;
        }
        Map<Integer, UserConfigEntity> userConfigMap = userConfigEntityList.stream().collect(Collectors.toMap(UserConfigEntity::getItem, t -> t, (t1, t2) -> t1));

        // 水印
        UserConfigEntity watermarkConfig = userConfigMap.get(ComboConfigItemEnum.WATERMARK.getCode());
        if (Objects.nonNull(watermarkConfig)) {
            response.setWatermark(watermarkConfig.getAvailable());
        }
        // 坑位
        ComboConfigItemEnum slotITem = itemMap.get(ComboConfigItemEnum.SLOT.getCode());
        if (Objects.nonNull(slotITem)) {
            UserConfigEntity slotConfig = userConfigMap.get(ComboConfigItemEnum.SLOT.getCode());
            if (Objects.nonNull(slotConfig)) {
                response.setTotalSlotNumber(slotConfig.getAvailable());
                Integer useSlot = slotMapper.slotStatistics(userId);
                if (Objects.nonNull(useSlot)) {
                    response.setUseSlotNumber(useSlot);
                }
                int availableSlot = response.getTotalSlotNumber() - response.getUseSlotNumber();
                response.setAvailableSlotNumber(Math.max(availableSlot, 0));
            }
        }
        ComboConfigItemEnum impressionsItem = itemMap.get(ComboConfigItemEnum.IMPRESSIONS.getCode());
        ComboConfigItemEnum identify = itemMap.get(ComboConfigItemEnum.IDENTIFY.getCode());
        ComboConfigItemEnum video = itemMap.get(ComboConfigItemEnum.VIDEO.getCode());
        ComboConfigItemEnum u3dModel = itemMap.get(ComboConfigItemEnum.UNITY3D_MODEL.getCode());
        // 浏览次数
        if (Objects.nonNull(impressionsItem)) {
            WorkStatisticsDTO workImpressionsStatistics = worksMapper.workImpressionsStatistics(userId);
            UserConfigEntity impressionsConfig = userConfigMap.get(ComboConfigItemEnum.IMPRESSIONS.getCode());
            if (Objects.nonNull(impressionsConfig)) {
                response.setTotalImpressionsNumber(impressionsConfig.getAvailable());
                if (Objects.nonNull(workImpressionsStatistics)) {
                    int useImpressions = workImpressionsStatistics.getImpressions() != null ? workImpressionsStatistics.getImpressions() : 0;
                    response.setUseImpressionsNumber(useImpressions);
                }
                int availableImpressions = response.getTotalImpressionsNumber() - response.getUseImpressionsNumber();
                response.setAvailableImpressionsNumber(Math.max(availableImpressions, 0));
            }
        }
        if (Objects.nonNull(identify) || Objects.nonNull(video) || Objects.nonNull(u3dModel)) {
            // 统计作品数量
            WorkStatisticsDTO workStatisticsDto = worksMapper.workStatistics(userId);
            WorkStatisticsDTO workDraftStatisticsDto = worksDraftMapper.worksDraftStatistics(userId);
            if (Objects.nonNull(identify)) {
                // 识别图大小
                UserConfigEntity userConfigEntity = userConfigMap.get(ComboConfigItemEnum.IDENTIFY.getCode());
                if (Objects.nonNull(userConfigEntity)) {
                    response.setTotalIdentifyNumber(userConfigEntity.getAvailable());
                    int useSize = 0;
                    if (Objects.nonNull(workStatisticsDto)) {
                        useSize = workStatisticsDto.getIdentify() != null ? workStatisticsDto.getIdentify() : 0;
                    }
                    if (Objects.nonNull(workDraftStatisticsDto)) {
                        useSize = useSize + (workDraftStatisticsDto.getIdentify() != null ? workDraftStatisticsDto.getIdentify() : 0);
                    }
                    response.setUseIdentifyNumber(useSize);
                    int availableSize = response.getTotalIdentifyNumber() - useSize;
                    response.setAvailableIdentifyNumber(Math.max(availableSize, 0));
                }
            }
            if (Objects.nonNull(video)) {
                // 视频大小
                UserConfigEntity userConfigEntity = userConfigMap.get(ComboConfigItemEnum.VIDEO.getCode());
                if (Objects.nonNull(userConfigEntity)) {
                    response.setTotalVideoNumber(userConfigEntity.getAvailable());
                    int useSize = 0;
                    if (Objects.nonNull(workStatisticsDto)) {
                        useSize = workStatisticsDto.getVideo() != null ? workStatisticsDto.getVideo() : 0;
                    }
                    if (Objects.nonNull(workDraftStatisticsDto)) {
                        useSize = useSize + (workDraftStatisticsDto.getVideo() != null ? workDraftStatisticsDto.getVideo() : 0);
                    }
                    response.setUseVideoNumber(useSize);
                    int availableSize = response.getTotalVideoNumber() - useSize;
                    response.setAvailableVideoNumber(Math.max(availableSize, 0));
                }
            }
            if (Objects.nonNull(u3dModel)) {
                // 3D模型大小
                UserConfigEntity userConfigEntity = userConfigMap.get(ComboConfigItemEnum.UNITY3D_MODEL.getCode());
                if (Objects.nonNull(userConfigEntity)) {
                    response.setTotalU3dModelNumber(userConfigEntity.getAvailable());
                    int useSize = 0;
                    if (Objects.nonNull(workStatisticsDto)) {
                        useSize = workStatisticsDto.getU3dModel() != null ? workStatisticsDto.getU3dModel() : 0;
                    }
                    if (Objects.nonNull(workDraftStatisticsDto)) {
                        useSize = useSize + (workDraftStatisticsDto.getU3dModel() != null ? workDraftStatisticsDto.getU3dModel() : 0);
                    }
                    response.setUseU3dModelNumber(useSize);
                    int availableSize = response.getTotalU3dModelNumber() - useSize;
                    response.setAvailableU3dModelNumber(Math.max(availableSize, 0));
                }
            }
        }
        return response;
    }

    /**
     * 用户授权
     *
     * @param userProfile 用户信息
     * @return 授权结果
     */
    @Transactional(rollbackFor = Throwable.class)
    public Result<UserAuthorizationResponse> authorization(UserProfile userProfile) {
        UserInfoEntity userInfo = userInfoMapper.findByUserId(userProfile.getId());
        if (Objects.nonNull(userInfo)) {
            return Result.success();
        }
        ComboEntity comboEntity = comboMapper.findByGrade(ComboGradeEnum.ORDINARY.getCode());
        UserInfoEntity userInfoEntity = buildUserInfo(userProfile.getId(), userProfile.getMobile(), comboEntity);
        userInfoRepository.save(userInfoEntity);
        List<UserConfigEntity> userConfigEntityList = getUserConfig(userProfile.getId(), userProfile.getMobile(), comboEntity);
        userConfigMapper.saveAll(userConfigEntityList);
        return Result.success();
    }

    /**
     * 批量授权用户
     *
     * @param userProfile 授权
     */
    @Transactional(rollbackFor = Throwable.class)
    public void authorizationByList(UserProfile userProfile, List<Long> userList, ComboEntity comboEntity) {
        List<UserInfoEntity> userInfoEntityList = userInfoMapper.queryByUserIdList(userList.stream().map(String::valueOf).collect(Collectors.toList()));
        if (CollectionUtils.isNotEmpty(userInfoEntityList)) {
            userList = userList.stream().filter(e -> !userInfoEntityList.stream().map(UserInfoEntity::getUserId).collect(Collectors.toList()).contains(e)).collect(Collectors.toList());
        }
        if (CollectionUtils.isEmpty(userList)) {
            return;
        }
        List<UserInfoEntity> userInfoEntities = new ArrayList<>();
        List<UserConfigEntity> userConfigEntities = new ArrayList<>();
        for (Long userId : userList) {
            UserInfoEntity userInfoEntity = this.buildUserInfo(userId, userProfile.getMobile(), comboEntity);
            List<UserConfigEntity> userConfigEntityList = this.getUserConfig(userId, userProfile.getMobile(), comboEntity);
            userInfoEntities.add(userInfoEntity);
            userConfigEntities.addAll(userConfigEntityList);
        }
        userInfoMapper.saveAll(userInfoEntities);
        List<List<UserConfigEntity>> userConfigPartition = Lists.partition(userConfigEntities, 1000);
        for (List<UserConfigEntity> configEntities : userConfigPartition) {
            userConfigMapper.saveAll(configEntities);
        }
    }

    /**
     * 反馈与建议
     *
     * @param userProfile     用户信息
     * @param feedbackRequest 请求
     * @return 响应
     */
    public FeedbackResponse feedback(UserProfile userProfile, FeedbackRequest feedbackRequest) {
        Date date = new Date();
        Integer productCategory = feedbackRequest.getProductCategory();
        if (Objects.isNull(productCategory)) {
            productCategory = ProductCategoryEnum.QUICK_AR.getCode();
        }
        FeedbackEntity feedback = new FeedbackEntity();
        feedback.setUserId(userProfile.getId());
        feedback.setProductCategory(productCategory);
        feedback.setContent(feedbackRequest.getContent());
        feedback.setCreatedAt(date);
        feedback.setCreator(userProfile.getMobile());
        feedback.setUpdatedAt(date);
        feedbackRepository.save(feedback);
        return new FeedbackResponse();
    }

    /**
     * 校验用户权益
     *
     * @param userProfile 用户信息
     * @param items       校验权益项
     * @return 响应
     */
    public VerifyRightsResponse verifyUserRights(UserProfile userProfile, String items) {
        Map<Integer, ComboConfigItemEnum> itemMap = this.getQueryItem(items);
        if (StringUtils.isNotBlank(items) && itemMap.isEmpty()) {
            throw new APIRuntimeException(ResultCodeEnum.USER_RIGHT_PARAM_ITEM_ERROR);
        }
        UserRightsResponse data = this.userRights(userProfile, itemMap);
        VerifyRightsResponse response = new VerifyRightsResponse();
        if (itemMap.get(ComboConfigItemEnum.SLOT.getCode()) != null && data.getAvailableSlotNumber() <= 0) {
            response.setTotalNumber(data.getTotalSlotNumber());
            response.setUseNumber(data.getUseSlotNumber());
            response.setAvailable(false);
            response.setReason(ResultCodeEnum.NO_SLOT_AVAILABLE.getMsg());
        } else if (itemMap.get(ComboConfigItemEnum.IMPRESSIONS.getCode()) != null && data.getAvailableImpressionsNumber() <= 0) {
            response.setTotalNumber(data.getTotalImpressionsNumber());
            response.setUseNumber(data.getUseImpressionsNumber());
            response.setAvailable(false);
            response.setReason(ResultCodeEnum.IMPRESSIONS_LIMIT.getMsg());
        } else if (itemMap.get(ComboConfigItemEnum.IDENTIFY.getCode()) != null && data.getAvailableIdentifyNumber() <= 0) {
            response.setTotalNumber(data.getTotalIdentifyNumber());
            response.setUseNumber(data.getUseIdentifyNumber());
            response.setAvailable(false);
            response.setReason("可用识别图小于0，请升级会员");
        } else if (itemMap.get(ComboConfigItemEnum.VIDEO.getCode()) != null && data.getAvailableIdentifyNumber() <= 0) {
            response.setTotalNumber(data.getTotalVideoNumber());
            response.setUseNumber(data.getUseVideoNumber());
            response.setAvailable(false);
            response.setReason("可用视频小于0，请升级会员");
        } else if (itemMap.get(ComboConfigItemEnum.UNITY3D_MODEL.getCode()) != null && data.getAvailableIdentifyNumber() <= 0) {
            response.setTotalNumber(data.getTotalU3dModelNumber());
            response.setUseNumber(data.getUseU3dModelNumber());
            response.setAvailable(false);
            response.setReason("可用视频小于0，请升级会员");
        }
        return response;
    }

    /**
     * 获取查询的item
     *
     * @param items items字符串（,号隔开）
     * @return item
     */
    public Map<Integer, ComboConfigItemEnum> getQueryItem(String items) {
        Map<Integer, ComboConfigItemEnum> itemMap = new HashMap<>();
        if (StringUtils.isNotBlank(items)) {
            String[] itemSplit = items.split(",");
            for (String item : itemSplit) {
                ComboConfigItemEnum comboItemEnum = ComboConfigItemEnum.getByItem(item);
                if (Objects.nonNull(comboItemEnum)) {
                    itemMap.put(comboItemEnum.getCode(), comboItemEnum);
                }
            }
        } else {
            itemMap = Arrays.stream(ComboConfigItemEnum.values()).collect(Collectors.toMap(ComboConfigItemEnum::getCode, Function.identity()));
        }
        return itemMap;
    }

    /**
     * 用户会员到期
     */
    @Transactional(rollbackFor = Throwable.class)
    public void userMemberExpired() {
        Date dayStartTime = DateTimeUtils.getDayStartTime(new Date());
        // 1、查询用户会员已经过期的用户
        List<UserInfoEntity> userInfoEntityList = userInfoMapper.findComboExpired(new Date());
        if (CollectionUtils.isEmpty(userInfoEntityList)) {
            log.info("没有套餐过期的用户");
            return;
        }
        // 查询默认套餐
        ComboEntity comboEntities = comboMapper.findByGrade(ComboGradeEnum.ORDINARY.getCode());
        ComboListResponse comboResponseList = ComboMapStruct.INSTANCE.entityToListResponse(comboEntities);
        Map<String, ComboConfigInfoVO> configInfoVoMap = comboResponseList.getConfig().stream().collect(Collectors.toMap(ComboConfigInfoVO::getItem, t -> t, (t1, t2) -> t1));

        List<List<UserInfoEntity>> userPartition = Lists.partition(userInfoEntityList, 100);
        for (List<UserInfoEntity> userInfoEntities : userPartition) {
            List<Long> userIdList = userInfoEntities.stream().map(UserInfoEntity::getUserId).collect(Collectors.toList());
            for (UserInfoEntity userInfoEntity : userInfoEntities) {
                Integer amount = configInfoVoMap.get(ComboConfigItemEnum.SLOT.getItem()).getAmount();
                Integer slotStatistics = slotMapper.slotStatistics(userInfoEntity.getUserId());
                if (slotStatistics > amount) {
                    int deleteAmount = slotStatistics - amount;
                    // 2、删除已经绑定该套餐的产品
                    List<SlotEntity> slotEntityList = slotMapper.queryByUserIdLimit(userInfoEntity.getUserId(), deleteAmount);
                    if (CollectionUtils.isNotEmpty(slotEntityList)) {
                        // 该套餐没有坑位
                        List<Long> slotIdList = slotEntityList.stream().map(SlotEntity::getId).collect(Collectors.toList());
                        slotMapper.batchDelete(slotIdList, slotIdList.size());

                        // 3、下线已经发布的产品
                        List<Long> workIdList = slotEntityList.stream().map(SlotEntity::getWorksId).collect(Collectors.toList());
                        if (CollectionUtils.isNotEmpty(workIdList)) {
                            // 批量下线
                            worksMapper.batchOffline(workIdList, workIdList.size());
                            // 作品下线，删除作品分享的用户
                            userWorksMapper.deleteBySourceWorks(workIdList, UserWorksTypeEnum.MINE.getCode(), UserWorksSourceEnum.SHARE.getCode());
                        }
                    }
                }
            }
            // 4、删除用户的套餐过期时间，修改用户等级、套餐id
            List<Long> userInfoIdList = userInfoEntities.stream().map(UserInfoEntity::getId).collect(Collectors.toList());
            ComboEntity comboEntity = comboMapper.findByGrade(ComboGradeEnum.ORDINARY.getCode());
            userInfoMapper.resetOrdinaryMember(ComboGradeEnum.ORDINARY.getCode(), comboEntity.getId(), userInfoIdList);
            // 5、修改用户配置
            List<UserConfigEntity> userConfigEntityList = userConfigMapper.findAllByUserId(userIdList);
            if (CollectionUtils.isNotEmpty(userConfigEntityList)) {
                // 修改用户配置为基础套餐
                Map<Long, List<UserConfigEntity>> userConfigMap = userConfigEntityList.stream().collect(Collectors.groupingBy(UserConfigEntity::getUserId));
                for (UserInfoEntity userInfoEntity : userInfoEntities) {
                    // 用户套餐
                    // 恢复默认套餐
                    List<UserConfigEntity> userConfigEntities = userConfigMap.get(userInfoEntity.getUserId());
                    for (UserConfigEntity userConfigEntity : userConfigEntities) {
                        ComboConfigItemEnum comboConfigItemEnum = ComboConfigItemEnum.getByCode(userConfigEntity.getItem());
                        ComboConfigInfoVO configInfoVO = configInfoVoMap.get(comboConfigItemEnum.getItem());
                        userConfigMapper.updateAvailable(userConfigEntity.getId(), configInfoVO.getAmount(), new Date(), "系统扣减");
                    }
                }
            }
        }
    }

    /**
     * 用户使用
     *
     * @param userProfile 用户信息
     * @return 使用结果
     */
    public Result<UserUseResponse> use(UserProfile userProfile) {
        userInfoMapper.noFirstUse(userProfile.getId());
        return Result.success();
    }

    public void updateUserCombo(Long userId, Long comboId, Date startTime, Date endTime) {
        UserInfoEntity userInfo = userInfoMapper.findByUserId(userId);
        userInfo.setComboId(comboId);
        if (userInfo.getComboStartTime() == null) {
            userInfo.setComboStartTime(startTime);
        }
        userInfo.setComboEndTime(endTime);
        userInfoRepository.save(userInfo);
    }

    /**
     * 素材过期
     */
    public void materialExpired(Date startTime, Date endTime) {
        Set<String> deletedWorksList = new HashSet<>();
        Set<String> worksList = new HashSet<>();
        List<String> needDeletedList = new ArrayList<>();

        List<WorksEntity> deletedWorksEntities = worksMapper.queryByDeletedAndUpdatedAt(DeletedEnum.TRUE.getCode(), startTime, endTime);
        if (CollectionUtils.isNotEmpty(deletedWorksEntities)) {
            for (WorksEntity entity : deletedWorksEntities) {
                Set<String> linkUrl = resolveUrl(entity.getIdentify(), entity.getContent());
                if (CollectionUtils.isNotEmpty(linkUrl)) {
                    deletedWorksList.addAll(linkUrl);
                }
            }
        }
        List<WorksDraftEntity> deletedWorksDraftEntities = worksDraftMapper.queryByDeletedAndUpdatedAt(DeletedEnum.TRUE.getCode(), startTime, endTime);
        if (CollectionUtils.isNotEmpty(deletedWorksDraftEntities)) {
            for (WorksDraftEntity entity : deletedWorksDraftEntities) {
                Set<String> linkUrl = resolveUrl(entity.getIdentify(), entity.getContent());
                if (CollectionUtils.isNotEmpty(linkUrl)) {
                    deletedWorksList.addAll(linkUrl);
                }
            }
        }
        List<WorksPreviewEntity> deletedWorksPreviewEntities = worksPreviewMapper.queryByDeletedAndUpdatedAt(DeletedEnum.TRUE.getCode(), startTime, endTime);
        if (CollectionUtils.isNotEmpty(deletedWorksPreviewEntities)) {
            for (WorksPreviewEntity entity : deletedWorksPreviewEntities) {
                Set<String> linkUrl = resolveUrl(entity.getIdentify(), entity.getContent());
                if (CollectionUtils.isNotEmpty(linkUrl)) {
                    deletedWorksList.addAll(linkUrl);
                }
            }
        }

        // 以下是在用的
        List<WorksEntity> worksEntities = worksMapper.queryByDeletedAndUpdatedAt(DeletedEnum.FALSE.getCode(), null, null);
        if (CollectionUtils.isNotEmpty(worksEntities)) {
            for (WorksEntity entity : worksEntities) {
                Set<String> linkUrl = resolveUrl(entity.getIdentify(), entity.getContent());
                if (CollectionUtils.isNotEmpty(linkUrl)) {
                    worksList.addAll(linkUrl);
                }
            }
        }
        List<WorksDraftEntity> worksDraftEntities = worksDraftMapper.queryByDeletedAndUpdatedAt(DeletedEnum.FALSE.getCode(), null, null);
        if (CollectionUtils.isNotEmpty(worksDraftEntities)) {
            for (WorksDraftEntity entity : worksDraftEntities) {
                Set<String> linkUrl = resolveUrl(entity.getIdentify(), entity.getContent());
                if (CollectionUtils.isNotEmpty(linkUrl)) {
                    worksList.addAll(linkUrl);
                }
            }
        }
        List<WorksPreviewEntity> worksPreviewEntities = worksPreviewMapper.queryByDeletedAndUpdatedAt(DeletedEnum.FALSE.getCode(), null, null);
        if (CollectionUtils.isNotEmpty(worksPreviewEntities)) {
            for (WorksPreviewEntity entity : worksPreviewEntities) {
                Set<String> linkUrl = resolveUrl(entity.getIdentify(), entity.getContent());
                if (CollectionUtils.isNotEmpty(linkUrl)) {
                    worksList.addAll(linkUrl);
                }
            }
        }
        List<WorksTemplateEntity> worksTemplateEntities = worksTemplateRepository.findAll();
        if (CollectionUtils.isNotEmpty(worksTemplateEntities)) {
            for (WorksTemplateEntity entity : worksTemplateEntities) {
                Set<String> linkUrl = resolveUrl(entity.getIdentify(), entity.getConfig());
                if (CollectionUtils.isNotEmpty(linkUrl)) {
                    worksList.addAll(linkUrl);
                }
            }
        }
        // 排除系统的素材
        List<MaterialsEntity> materialsEntities = materialMapper.queryAllLinkUrl();
        if (CollectionUtils.isNotEmpty(materialsEntities)) {
            worksList.addAll(materialsEntities.stream().filter(Objects::nonNull).map(MaterialsEntity::getLinkUrl).collect(Collectors.toList()));
        }

        // 删除作品排除未删除的
        for (String linkUrl : deletedWorksList) {
            if (StringUtils.isNotBlank(linkUrl) && !worksList.contains(linkUrl)) {
                needDeletedList.add(linkUrl);
            }
        }
        if (CollectionUtils.isNotEmpty(needDeletedList)) {
            List<String> deletedFail = fileReference.productFileBatchDelete(needDeletedList);
            if (CollectionUtils.isNotEmpty(deletedFail)) {
                String failDeletedUrl = String.join("\n", deletedFail);
                log.error("系统批量删除资源文件失败的URL：[{}]", failDeletedUrl);
            }
        }
    }

    /**
     * 解析url
     *
     * @param identify 识别图
     * @param content  内容
     * @return 响应
     */
    private Set<String> resolveUrl(String identify, String content) {
        Set<String> resultList = new HashSet<>();
        try {
            JSONObject identifyObject = JSONObject.parseObject(identify);
            if (identifyObject != null) {
                resultList.add(identifyObject.getString("linkUrl"));
            }
        } catch (Exception e) {
            // 解析识别图异常
        }
        try {
            List<WorksContentDTO> worksContentDTOList = JSON.parseArray(content, WorksContentDTO.class);
            Set<String> contentLinkUrlList = Optional.ofNullable(worksContentDTOList).orElse(Collections.emptyList()).stream().map(WorksContentDTO::getLinkUrl).collect(Collectors.toSet());
            if (CollectionUtils.isNotEmpty(contentLinkUrlList)) {
                resultList.addAll(contentLinkUrlList);
            }
        } catch (Exception e) {
            // 解析内容异常
        }
        return resultList;
    }

    /**
     * 变更配置
     *
     * @param userProfile 用户信息
     * @param request     变更配置请求
     * @return 变更后用户配置
     */
    @Transactional(rollbackFor = Throwable.class)
    public UserConfigResponse changeConfig(UserProfile userProfile, ChangeConfigRequest request) {
        if (CollectionUtils.isEmpty(request.getUserId())) {
            throw new APIRuntimeException(ResultCodeEnum.USER_NOT_NULL);
        }
        UserConfigChangeMethodEnum changeMethodEnum = UserConfigChangeMethodEnum.getByCode(request.getChangeMethod());
        if (changeMethodEnum == null) {
            throw new APIRuntimeException(ResultCodeEnum.CHANGE_METHOD_ERROR);
        }
        List<UserConfigEntity> userConfigEntityList = userConfigMapper.findAllByUserId(request.getUserId());
        Map<Integer, List<UserConfigEntity>> userConfigItemMap = userConfigEntityList.stream().collect(Collectors.groupingBy(UserConfigEntity::getItem));
        Date updatedTime = new Date();
        // 水印
        if (request.getWatermark() != null) {
            List<UserConfigEntity> userConfigEntities = userConfigItemMap.get(ComboConfigItemEnum.WATERMARK.getCode());
            userConfigEntities.forEach(e -> {
                e.setAvailable(request.getWatermark());
                e.setOperator(userProfile.getMobile());
                e.setUpdatedAt(updatedTime);
            });
        }
        // 坑位
        if (request.getSlotNumber() != null && request.getSlotNumber() != 0) {
            List<UserConfigEntity> userConfigEntities = userConfigItemMap.get(ComboConfigItemEnum.SLOT.getCode());
            this.updateAvailable(userConfigEntities, changeMethodEnum, request.getSlotNumber(), userProfile.getMobile(), updatedTime);
        }
        // 识别次数
        if (request.getImpressionsNumber() != null && request.getImpressionsNumber() != 0) {
            List<UserConfigEntity> userConfigEntities = userConfigItemMap.get(ComboConfigItemEnum.IMPRESSIONS.getCode());
            this.updateAvailable(userConfigEntities, changeMethodEnum, request.getImpressionsNumber(), userProfile.getMobile(), updatedTime);
        }
        // 识别图大小
        if (request.getIdentifyNumber() != null && request.getIdentifyNumber() != 0) {
            List<UserConfigEntity> userConfigEntities = userConfigItemMap.get(ComboConfigItemEnum.IDENTIFY.getCode());
            this.updateAvailable(userConfigEntities, changeMethodEnum, request.getIdentifyNumber(), userProfile.getMobile(), updatedTime);
        }
        // 视频大小
        if (request.getVideoNumber() != null && request.getVideoNumber() != 0) {
            List<UserConfigEntity> userConfigEntities = userConfigItemMap.get(ComboConfigItemEnum.VIDEO.getCode());
            this.updateAvailable(userConfigEntities, changeMethodEnum, request.getVideoNumber(), userProfile.getMobile(), updatedTime);
        }
        // 3d模型大小
        if (request.getU3dModelNumber() != null && request.getU3dModelNumber() != 0) {
            List<UserConfigEntity> userConfigEntities = userConfigItemMap.get(ComboConfigItemEnum.UNITY3D_MODEL.getCode());
            this.updateAvailable(userConfigEntities, changeMethodEnum, request.getU3dModelNumber(), userProfile.getMobile(), updatedTime);
        }
        List<UserConfigEntity> userConfigEntities = userConfigRepository.saveAll(userConfigEntityList);
        Map<Long, List<UserConfigEntity>> resultEntityMap = userConfigEntities.stream().collect(Collectors.groupingBy(UserConfigEntity::getUserId));
        List<UserConfigVO> userConfigs = new ArrayList<>(resultEntityMap.size());
        resultEntityMap.forEach((key, value) -> {
            UserConfigVO userConfigVo = new UserConfigVO();
            userConfigVo.setUserId(key);
            Map<Integer, UserConfigEntity> valueMap = value.stream().collect(Collectors.toMap(UserConfigEntity::getItem, t -> t, (t1, t2) -> t1));
            UserConfigEntity watermark = valueMap.get(ComboConfigItemEnum.WATERMARK.getCode());
            userConfigVo.setWatermark(watermark.getAvailable());
            UserConfigEntity slot = valueMap.get(ComboConfigItemEnum.SLOT.getCode());
            userConfigVo.setSlotNumber(slot.getAvailable());
            UserConfigEntity impressions = valueMap.get(ComboConfigItemEnum.IMPRESSIONS.getCode());
            userConfigVo.setImpressionsNumber(impressions.getAvailable());
            UserConfigEntity identify = valueMap.get(ComboConfigItemEnum.IDENTIFY.getCode());
            userConfigVo.setIdentifyNumber(identify.getAvailable());
            UserConfigEntity video = valueMap.get(ComboConfigItemEnum.VIDEO.getCode());
            userConfigVo.setVideoNumber(video.getAvailable());
            UserConfigEntity unity3dModel = valueMap.get(ComboConfigItemEnum.UNITY3D_MODEL.getCode());
            userConfigVo.setU3dModelNumber(unity3dModel.getAvailable());
            userConfigs.add(userConfigVo);
        });
        UserConfigResponse response = new UserConfigResponse();
        response.setUserConfigs(userConfigs);
        return response;
    }

    /**
     * 批量更新值
     *
     * @param userConfigEntities 用户配置
     * @param changeMethodEnum   变更方式
     * @param available          可用值
     * @param operator           操作人
     * @param updatedAt          更新时间
     */
    private void updateAvailable(List<UserConfigEntity> userConfigEntities, UserConfigChangeMethodEnum changeMethodEnum, Integer available, String operator, Date updatedAt) {
        userConfigEntities.forEach(e -> {
            if (UserConfigChangeMethodEnum.APPEND.equals(changeMethodEnum)) {
                e.setAvailable(e.getAvailable() + available);
            } else {
                e.setAvailable(available);
            }
            e.setOperator(operator);
            e.setUpdatedAt(updatedAt);
        });
    }

    /**
     * 意见反馈列表查询
     *
     * @param pageNum         当前页
     * @param pageSize        页记录数
     * @param productCategory 产品类别
     * @return
     */
    public Result<PageResult<FeedbackListResponse>> feedbackList(Integer pageNum, Integer pageSize, String productCategory) {
        Page<Object> page = PageHelper.startPage(pageNum, pageSize);
        List<FeedbackEntity> feedbackEntities = feedbackMapper.queryPage(StringUtils.isNotBlank(productCategory) ? Integer.parseInt(productCategory) : null);
        if (CollectionUtils.isEmpty(feedbackEntities)) {
            return Result.success(new PageResult<>());
        }
        List<FeedbackListResponse> feedbackListResponseList = FeedbackMapStruct.INSTANCE.entitiesToListResponses(feedbackEntities);
        PageInfo<FeedbackListResponse> feedbackListResponsePageInfo = new PageInfo<>(feedbackListResponseList);
        feedbackListResponsePageInfo.setPageNum(pageNum);
        feedbackListResponsePageInfo.setTotal(page.getTotal());
        return PageUtils.getPageResult(feedbackListResponsePageInfo, feedbackListResponseList);
    }

    /**
     * 会员支付成功处理
     */
    @Transactional(rollbackFor = Throwable.class)
    public void memberPaySuccess(WechatPrepayAttachInfo attachInfo) {
        //支付成功，更新用户套餐
        UserInfoEntity userInfo = userInfoMapper.findByUserId(attachInfo.getUserId());
        userInfo.setComboId(attachInfo.getComboId());
        if (userInfo.getComboStartTime() == null) {
            userInfo.setComboStartTime(attachInfo.getStartTime());
        }
        userInfo.setComboEndTime(attachInfo.getEndTime());
        userInfoRepository.save(userInfo);
        //支付成功，更新用户套餐配置
        Optional<ComboEntity> comboEntityOptional = comboRepository.findById(attachInfo.getComboId());
        ComboEntity comboEntity = comboEntityOptional.orElse(null);
        List<ComboConfigInfoVO> configInfoVOList = ComboMapStruct.INSTANCE.configConvert(comboEntity.getConfig());
        Map<String, ComboConfigInfoVO> configInfoVoMap = configInfoVOList.stream()
                .collect(Collectors.toMap(ComboConfigInfoVO::getItem, t -> t, (t1, t2) -> t1));
        List<UserConfigEntity> userConfigEntities = userConfigMapper.findByUserId(attachInfo.getUserId());
        for (UserConfigEntity userConfigEntity : userConfigEntities) {
            ComboConfigItemEnum comboConfigItemEnum = ComboConfigItemEnum.getByCode(userConfigEntity.getItem());
            ComboConfigInfoVO configInfoVO = configInfoVoMap.get(comboConfigItemEnum.getItem());
            userConfigMapper.updateAvailable(userConfigEntity.getId(), configInfoVO.getAmount(), new Date(),
                    "支付回调");
        }
        Integer limit = configInfoVoMap.get(ComboConfigItemEnum.SLOT.getItem()).getAmount();
        Integer slotCount = slotMapper.slotStatistics(attachInfo.getUserId());
        if (limit != null && slotCount != null && limit > slotCount) {
            Integer onlineCount = limit - slotCount;
            List<WorksEntity> worksEntities = worksMapper.queryUserOfflineOrderByCreatedAt(
                    attachInfo.getUserId(), onlineCount);
            if (com.gxar.common.utils.CollectionUtils.isNotEmpty(worksEntities)) {
                //支付成功，更新作品状态
                List<Long> workIds = worksEntities.stream().map(WorksEntity::getId)
                        .collect(Collectors.toList());
                worksMapper.batchOnline(workIds, workIds.size());
                //支付成功，更新坑位状态
                List<Long> slotIds = worksEntities.stream().map(WorksEntity::getSlotId)
                        .collect(Collectors.toList());
                slotMapper.batchAvailable(slotIds, slotIds.size(), attachInfo.getEndTime());
            }
        }
    }

    /**
     * 分页查询用户信息
     *
     * @param userProfile    登录用户
     * @param pageNum        当前页
     * @param pageSize       页记录数
     * @param userId         用户ID
     * @param phone          手机号
     * @param templateNumber 模板数量
     * @param createdAtStart 创建开始日期
     * @param createdAtEnd   创建结束日期
     * @param updatedAtStart 更新开始日期
     * @param updatedAtEnd   结束开始日期
     * @return 响应
     */
    public Result<PageResult<AdminUserPageResponse>> pageList(UserProfile userProfile, int pageNum, int pageSize,
                                                              Long userId, String phone, Integer templateNumber,
                                                              String createdAtStart, String createdAtEnd,
                                                              String updatedAtStart, String updatedAtEnd) {
        // 发放数量
        List<Long> userIdCondition = new ArrayList<>();
        ExchangeItemSendUserStatisticsDTO statisticsNumber = null;
        if (Objects.nonNull(templateNumber)) {
            statisticsNumber = exchangeItemSendRecordMapper.findByStatisticsNumber(templateNumber);
        }
        if (Objects.nonNull(statisticsNumber)) {
            userIdCondition.add(statisticsNumber.getUserId());
        }
        // 用户id
        if (Objects.nonNull(userId)) {
            userIdCondition.add(userId);
        }
        String dateFormatString = "yyyy.MM.dd";
        // 创建时间
        Date createdAtStartDate = null;
        Date createdAtEndDate = null;
        if (StringUtils.isNotBlank(createdAtStart) || StringUtils.isNotBlank(createdAtEnd)) {
            if (StringUtils.isBlank(createdAtStart)) {
                createdAtStartDate = DateTimeUtils.getDayStartTime(new Date());
            } else {
                createdAtStartDate = DateTimeUtils.getDayStartTime(DateTimeUtils.parse(createdAtStart, dateFormatString));
            }
            if (StringUtils.isBlank(createdAtEnd)) {
                createdAtEndDate = DateTimeUtils.getDayEndTime(new Date());
            } else {
                createdAtEndDate = DateTimeUtils.getDayEndTime(DateTimeUtils.parse(createdAtEnd, dateFormatString));
            }
            boolean endBeforeStart = createdAtEndDate.compareTo(createdAtStartDate) < 0;
            if (endBeforeStart) {
                throw new APIRuntimeException(ResultCodeEnum.END_TIME_BERORE_START_TIME);
            }
        }
        // 更新时间
        Date updatedAtStartDate = null;
        Date updatedAtEndDate = null;
        if (StringUtils.isNotBlank(updatedAtStart) || StringUtils.isNotBlank(updatedAtEnd)) {
            if (StringUtils.isBlank(updatedAtStart)) {
                updatedAtStartDate = DateTimeUtils.getDayStartTime(new Date());
            } else {
                updatedAtStartDate = DateTimeUtils.getDayStartTime(DateTimeUtils.parse(updatedAtStart, dateFormatString));
            }
            if (StringUtils.isBlank(updatedAtEnd)) {
                updatedAtEndDate = DateTimeUtils.getDayEndTime(new Date());
            } else {
                updatedAtEndDate = DateTimeUtils.getDayEndTime(DateTimeUtils.parse(updatedAtEnd, dateFormatString));
            }
            boolean endBeforeStart = updatedAtEndDate.compareTo(updatedAtStartDate) < 0;
            if (endBeforeStart) {
                throw new APIRuntimeException(ResultCodeEnum.END_TIME_BERORE_START_TIME);
            }
        }
        if (StringUtils.isNotBlank(phone)) {
            UserProfile user = userReference.findUserByMobileWithAuthorize(null, null, phone, UserConstant.USER_NO_AUTO_REGISTER);
            if (Objects.isNull(user) || Objects.isNull(user.getId())) {
                return Result.success(new PageResult<>());
            } else {
                userIdCondition.add(user.getId());
            }
        }
        // 查询
        Page<Object> page = PageHelper.startPage(pageNum, pageSize);
        List<UserInfoEntity> userInfoEntityList = userInfoMapper.queryPage(userIdCondition, null, createdAtStartDate, createdAtEndDate, updatedAtStartDate, updatedAtEndDate);
        if (CollectionUtils.isEmpty(userInfoEntityList)) {
            return Result.success(new PageResult<>());
        }
        Map<Long, ExchangeItemSendUserStatisticsDTO> exchangeItemSendUserStatisticsMap = new HashMap<>();
        List<Long> userIdList = userInfoEntityList.stream().map(UserInfoEntity::getUserId).collect(Collectors.toList());
        if (Objects.isNull(templateNumber)) {
            List<ExchangeItemSendUserStatisticsDTO> exchangeItemSendUserStatistics = exchangeItemSendRecordMapper.statisticsInUserId(userIdList);
            exchangeItemSendUserStatisticsMap = Optional.ofNullable(exchangeItemSendUserStatistics).orElse(Collections.emptyList()).stream()
                    .collect(Collectors.toMap(ExchangeItemSendUserStatisticsDTO::getUserId, t -> t, (t1, t2) -> t1));
        }
        List<UserProfile> userProfiles = userReference.batchProfileByAuthorize(userIdList, null, null);
        Map<Long, UserProfile> userProfileMap = Optional.ofNullable(userProfiles).orElse(Collections.emptyList()).stream().collect(Collectors.toMap(UserProfile::getId, t -> t, (t1, t2) -> t1));
        List<AdminUserPageResponse> responses = UserMapStructImpl.INSTANCE.entitiesToPageResponses(userInfoEntityList);
        // 模板数量
        if (Objects.isNull(templateNumber)) {
            for (AdminUserPageResponse response : responses) {
                ExchangeItemSendUserStatisticsDTO statistics = exchangeItemSendUserStatisticsMap.get(response.getUserId());
                response.setTemplateNumber(statistics != null ? statistics.getNumber() : 0);
                response.setCreator(userProfileMap.get(response.getUserId()) != null ? userProfileMap.get(response.getUserId()).getMobile() : response.getCreator());
            }
        } else {
            for (AdminUserPageResponse response : responses) {
                response.setTemplateNumber(templateNumber);
                response.setCreator(userProfileMap.get(response.getUserId()) != null ? userProfileMap.get(response.getUserId()).getMobile() : response.getCreator());
            }
        }
        PageInfo<AdminUserPageResponse> responsePageInfo = new PageInfo<>(responses);
        responsePageInfo.setPageNum(pageNum);
        responsePageInfo.setTotal(page.getTotal());
        return PageUtils.getPageResult(responsePageInfo, responses);
    }

    /**
     * 构建用户信息实体
     *
     * @param userId      用户ID
     * @param phone       创建人手机号
     * @param comboEntity 套餐实体
     * @return 响应
     */
    public UserInfoEntity buildUserInfo(Long userId, String phone, ComboEntity comboEntity) {
        UserInfoEntity userInfoEntity = new UserInfoEntity();
        userInfoEntity.setName("AR" + RandomNameUtil.getStringRandom(8));
        userInfoEntity.setUserId(userId);
        userInfoEntity.setCreatedAt(new Date());
        userInfoEntity.setCreator(phone);
        userInfoEntity.setUpdatedAt(new Date());
        userInfoEntity.setFirstUse(true);
        userInfoEntity.setComboId(comboEntity.getId());
        userInfoEntity.setGrade(comboEntity.getGrade());
        userInfoEntity.setDeleted(false);
        return userInfoEntity;
    }

    /**
     * 创建用户配置信息
     *
     * @param userId      用户ID
     * @param phone       创建者手机号
     * @param comboEntity 套餐实体
     * @return 响应
     */
    public List<UserConfigEntity> getUserConfig(Long userId, String phone, ComboEntity comboEntity) {
        String config = comboEntity.getConfig();
        JSONArray jsonArray = JSONObject.parseObject(config).getJSONArray("config");
        List<ComboConfigInfoVO> configInfoVOList = JSON.parseArray(JSON.toJSONString(jsonArray), ComboConfigInfoVO.class);
        List<UserConfigEntity> userConfigEntityList = new ArrayList<>();
        for (ComboConfigInfoVO configInfoVo : Optional.ofNullable(configInfoVOList).orElse(Collections.emptyList())) {
            String item = configInfoVo.getItem();
            ComboConfigItemEnum comboConfigItemEnum = ComboConfigItemEnum.getByItem(item);
            ComboConfigItemUnitEnum comboConfigItemUnitEnum = ComboConfigItemUnitEnum.getByName(configInfoVo.getUnit());
            if (Objects.nonNull(comboConfigItemEnum) && Objects.nonNull(comboConfigItemUnitEnum)) {
                UserConfigEntity userConfigEntity = new UserConfigEntity();
                userConfigEntity.setUserId(userId);
                userConfigEntity.setItem(comboConfigItemEnum.getCode());
                userConfigEntity.setAvailable(configInfoVo.getAmount());
                userConfigEntity.setUnit(comboConfigItemUnitEnum.getName());
                userConfigEntity.setCreatedAt(new Date());
                userConfigEntity.setCreator(phone);
                userConfigEntity.setUpdatedAt(new Date());
                userConfigEntityList.add(userConfigEntity);
            }
        }
        return userConfigEntityList;
    }

    /**
     * 根据创建者查询
     *
     * @param phone 手机号
     * @return 创建者
     */
    public UserInfoEntity findByCreator(String phone) {
        return userInfoMapper.findByCreator(phone);
    }

    /**
     * 根据用户ID查询
     *
     * @param userId 用户ID
     * @return 用户信息
     */
    public UserInfoEntity findByUserId(Long userId) {
        return userInfoMapper.findByUserId(userId);
    }

    /**
     * 保存用户信息
     *
     * @param userInfoEntity 用户信息
     * @return 用户信息
     */
    public UserInfoEntity save(UserInfoEntity userInfoEntity) {
        return userInfoRepository.save(userInfoEntity);
    }

    /**
     * 批量保存用户配置信息
     *
     * @param userConfigEntityList 用户配置信息
     */
    public void saveAllConfig(List<UserConfigEntity> userConfigEntityList) {
        userConfigMapper.saveAll(userConfigEntityList);
    }

    /**
     * 删除单个用户
     *
     * @param userProfile 用户信息
     * @param userId      用户ID
     */
    @Transactional(rollbackFor = Throwable.class)
    public void deleteUser(UserProfile userProfile, Long userId) {
        UserInfoEntity userInfo = userInfoMapper.findByUserId(userId);
        if (Objects.nonNull(userInfo)) {
            List<UserConfigEntity> userConfigEntityList = userConfigMapper.findByUserId(userId);
            userInfo.setDeleted(true);
            userInfo.setOperator(userProfile.getMobile());
            userInfo.setCreatedAt(new Date());
            userInfoRepository.save(userInfo);
            userConfigRepository.deleteAll(userConfigEntityList);
            List<Long> userIdList = new ArrayList<>(1);
            userIdList.add(userId);
            uaaReference.batchDelete(userIdList);

            //逻辑删除用户系统用户
            userReference.writeoffWithAuthorize("", "", userId);
        }
    }

    /**
     * 批量删除用户
     *
     * @param userProfile 用户信息
     * @param userIds     用户id集合
     */
    @Transactional(rollbackFor = Throwable.class)
    public void batchDeleteUser(UserProfile userProfile, List<String> userIds) {
        List<UserInfoEntity> userInfoEntityList = userInfoMapper.queryByUserIdList(userIds);
        if (CollectionUtils.isNotEmpty(userInfoEntityList)) {
            List<Long> userIdList = userInfoEntityList.stream().map(UserInfoEntity::getUserId).collect(Collectors.toList());
            List<UserConfigEntity> userConfigEntityList = userConfigMapper.findAllByUserId(userIdList);
            List<UserInfoEntity> deleted = new ArrayList<>();
            Date date = new Date();
            for (UserInfoEntity userInfoEntity : userInfoEntityList) {
                userInfoEntity.setDeleted(true);
                userInfoEntity.setOperator(userProfile.getMobile());
                userInfoEntity.setCreatedAt(date);
                deleted.add(userInfoEntity);
            }
            userInfoRepository.saveAll(deleted);
            userConfigRepository.deleteAll(userConfigEntityList);
            uaaReference.batchDelete(userIdList);

            //逻辑删除用户系统用户
            for (UserInfoEntity userInfo : deleted) {
                userReference.writeoffWithAuthorize("", "", userInfo.getUserId());
            }
        }


    }
}
